﻿using System;
using Combat;
using PrimeTween;
using UnityEngine;

namespace Visual
{
    public class RingVisual : MonoBehaviour
    {
        private enum State
        {
            Normal,
            Damaged,
            Dangerous
        }
        
        private static readonly int NoiseScale = Shader.PropertyToID("_NoiseScale");
        private static readonly int Intensity = Shader.PropertyToID("_Intensity");
        
        [SerializeField] private Color damagedColor;
        [SerializeField] private Color dangerousColor;
        [SerializeField] private float damagedNoise = 3f;
        
        [SerializeField] private SpriteRenderer spriteRenderer;
        
        private Health _health;
        private Material _material;
        
        private Color _normalColor;
        private float _normalNoise;
        private float _normalIntensity;
        
        private Tween _colorTween;
        private Tween _scaleTween;
        private Sequence _propertyTween;
        private Sequence _intensityTween;
        
        private State _state = State.Normal;

        private float _scale;


        private void Awake()
        {
            _health = GetComponent<Health>();
            _material = spriteRenderer.material;
            _normalColor = spriteRenderer.color;
            _normalNoise = _material.GetFloat(NoiseScale);
            _normalIntensity = _material.GetFloat(Intensity);
            _scale = transform.localScale.x;
            
            _health.HealthChanged += Health_HealthChanged;
            _health.Hit += Health_Hit;
            _health.Died += Health_Died;
            _health.Reborn += Health_Reborn;
        }

        private void Health_Hit(Vector2 obj)
        {
            _propertyTween.Stop();
            _intensityTween.Stop();

            _propertyTween = Sequence.Create()
                .Group(Tween.MaterialProperty(_material, NoiseScale, damagedNoise, 0.2f))
                .Chain(Tween.MaterialProperty(_material, NoiseScale, _normalNoise, 0.2f));
            _intensityTween = Sequence.Create()
                .Group(Tween.MaterialProperty(_material, Intensity, 2.5f, 0.2f))
                .Chain(Tween.MaterialProperty(_material, Intensity, _normalIntensity, 0.2f));
        }

        private void Health_Died()
        {
            _scaleTween.Stop();
            _scaleTween = Tween.Scale(transform, 0f, 0.5f);
        }
        
        private void Health_Reborn()
        {
            _scaleTween.Stop();
            _scaleTween = Tween.Scale(transform, _scale, 1f);
        }

        private void Health_HealthChanged()
        {
            // _material.SetFloat(Intensity, Mathf.Lerp(0.5f, 2f, _health.NormalizedHp));
            
            if (_health.Hp <= 1)
            {
                if (_state == State.Dangerous)
                {
                    return;
                }
                
                _state = State.Dangerous;
                _colorTween.Stop();
                _colorTween = Tween.Color(spriteRenderer, dangerousColor, 1f);
                
                return;
            }

            if (_health.NormalizedHp <= 0.5f)
            {
                if (_state == State.Damaged)
                {
                    return;
                }
                
                _state = State.Damaged;
                _colorTween.Stop();
                _colorTween = Tween.Color(spriteRenderer, damagedColor, 1f);
                
                return;
            }

            if (_state == State.Normal)
            {
                return;
            }
            
            _state = State.Normal;
            _colorTween.Stop();
            _colorTween = Tween.Color(spriteRenderer, _normalColor, 1f);
        }
    }
}